﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using SdmxMl.Common;
using SdmxMl.GenericMetadata;
using SdmxMl.Helper;
using SdmxMl.Structure;
using SdmxMl.Panels;
using SdmxMl.UC;

namespace SdmxMl.Manager
{
    #region delegates

    /// <summary> Publishes the Save artefact method definition in the form of a delegate </summary>
    /// <param name="sender"></param>/ <param name="e">Empty arg</param>
    public delegate void SaveArtefactEvent(object sender, EventArgs a);

    public delegate void CopyArtefactRefEvent(object sender, EventArgs a);

    #endregion

    public class TreeSdmxPopupMenuManager
    {
        #region Internal Members

        private ContextMenuStrip contextMenu;
        private MoveableTreeView tv;
        private ToolStripMenuItem saveSelectedArtefactToolStripMenuItem;
        private ToolStripButton toolStripButtonSaveArtefact;

        #endregion

        #region Menu types enumeration

        /// <summary>Indexes for popup menu items</summary>
        private enum PopupItem
        {
            NewChild = 0,
            Copy,
            Paste,
            DeleteItem,
            Separator1,
            RedefineParent,
            CopyArtefactRef,
            SaveDocument,
            NewVersion,
        }
        #endregion

        /// <summary> 
        /// An event generator to notify Tree Manager that Save Artefact is requested.
        /// </summary>
        public event SaveArtefactEvent SaveArtefactEventExposed;
        public event CopyArtefactRefEvent CopyArtefactRefEventExposed;

        #region Properties

        // Selected item can be saved as SDMX file ?
        public bool IsItemWritable
        {
            get
            {
                return contextMenu.Items[(int)PopupItem.SaveDocument].Enabled;
            }
        }

        private ucPanelDetail panelDetail;
        public ucPanelDetail PanelDetail
        {
            get { return panelDetail; }
            set
            {
                panelDetail = value;
            }
        }

        public ToolStripMenuItem SaveSelectedArtefactToolStripMenuItem
        {
            set { saveSelectedArtefactToolStripMenuItem = value;  }
        }

        public ToolStripButton ToolStripButtonSaveArtefact
        {
            set { toolStripButtonSaveArtefact = value; }
        }
        #endregion

        #region C'tor

        public TreeSdmxPopupMenuManager(MoveableTreeView mtv)
        {
            tv = mtv;
            CreateContextMenu();
            tv.ContextMenuStrip = contextMenu;
        }

        #endregion

        #region Create Popup Menu

        /// <summary>Popup menu for Operations on Tree Items</summary>
        private void CreateContextMenu()
        {
            contextMenu = new ContextMenuStrip();
            ToolStripMenuItem menuItemNewChild = new ToolStripMenuItem();
            ToolStripMenuItem menuItemCopyItem = new ToolStripMenuItem();
            ToolStripMenuItem menuItemPasteItem = new ToolStripMenuItem();
            ToolStripMenuItem menuItemDelete = new ToolStripMenuItem();
            ToolStripMenuItem menuItemRedefineParent = new ToolStripMenuItem();
            ToolStripMenuItem menuCopyArtefactRefItem = new ToolStripMenuItem();
            ToolStripMenuItem menuItemSaveArtefact = new ToolStripMenuItem();
            ToolStripMenuItem menuItemNewArtefactVersion = new ToolStripMenuItem();
          //  ToolStripMenuItem menuItemActivateUri = new ToolStripMenuItem();
            
            contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] 
            { menuItemNewChild, menuItemCopyItem, menuItemPasteItem, menuItemDelete, new ToolStripSeparator(),
                menuItemRedefineParent, menuCopyArtefactRefItem, menuItemSaveArtefact, 
                menuItemNewArtefactVersion });

           // menuItemActivateUri.Text = "Activates Uri link";
           // menuItemActivateUri.Image = global::SdmxMl.Properties.Resources.NEW16;
            //menuItemActivateUri.ShortcutKeys = ((System.Windows.Forms.Keys)(System.Windows.Forms.Keys.Insert));
            //menuItemActivateUri.Click +=new EventHandler(menuItemActivateUri_Click);

            menuItemNewChild.Text = "New Child";
            menuItemNewChild.Image = global::SdmxMl.Properties.Resources.NEW16;
            menuItemNewChild.ShortcutKeys = ((System.Windows.Forms.Keys)(System.Windows.Forms.Keys.Insert));
            menuItemNewChild.Click += new EventHandler(menuItemNewChild_Click);

            menuItemDelete.Text = "Remove Selected Item";
            menuItemDelete.Image = global::SdmxMl.Properties.Resources.non;
            menuItemDelete.ShortcutKeys = ((System.Windows.Forms.Keys)( System.Windows.Forms.Keys.Delete));
            menuItemDelete.Click += new EventHandler(menuItemDelete_Click);

            menuItemRedefineParent.Text = "Redefines Parent";
            menuItemRedefineParent.ShortcutKeys = ((System.Windows.Forms.Keys)
               ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P)));
            menuItemRedefineParent.Click += new EventHandler(menuItemRedefineParent_Click);

            menuItemNewArtefactVersion.Text = "New Artefact version";
            menuItemNewArtefactVersion.Image = global::SdmxMl.Properties.Resources.add_page_16;
            menuItemNewArtefactVersion.ShortcutKeys = ((System.Windows.Forms.Keys)
                ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
            menuItemNewArtefactVersion.Click += new EventHandler(menuItemNewArtefactVersion_Click);

            menuItemSaveArtefact.Text = "Save as SDMX Document";
            menuItemSaveArtefact.Image = global::SdmxMl.Properties.Resources.FOLDER01;
            menuItemSaveArtefact.ShortcutKeys = ((System.Windows.Forms.Keys)
                ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
            menuItemSaveArtefact.Click += new EventHandler(menuItemSaveArtefact_Click);

            menuItemCopyItem.Text = "Copy Item";
            menuItemCopyItem.Image = global::SdmxMl.Properties.Resources.copy;
            menuItemCopyItem.ShortcutKeys = ((System.Windows.Forms.Keys)
                ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
            menuItemCopyItem.Click += new EventHandler(menuItemCopyItem_Click);

            menuItemPasteItem.Text = "Paste Item";
            menuItemPasteItem.Image = global::SdmxMl.Properties.Resources.paste;
            menuItemPasteItem.ShortcutKeys = ((System.Windows.Forms.Keys)
                ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
            menuItemPasteItem.Click += new EventHandler(menuItemPasteItem_Click);

            menuCopyArtefactRefItem.Text = "Copy Artefact reference";
            menuCopyArtefactRefItem.Image = global::SdmxMl.Properties.Resources.Reference;
            menuCopyArtefactRefItem.ShortcutKeys = ((System.Windows.Forms.Keys)
                ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
            menuCopyArtefactRefItem.Click += new EventHandler(menuItemCopyArtefactRef_Click);
            
            UpdateContextMenu(null);
        }


        #endregion

        #region Update Popup items Enabling

        /// <summary>Enable items according to tree selection context</summary>
        /// <param name="node">selected node (can be null)</param>
        public void UpdateContextMenu(TreeNode node)
        {
            object tag = null;
            if (node != null)
                tag = node.Tag;

            // Update readonly information
            bool readOnly = false;
            Artefact artefact = tag as Artefact;
            if (artefact == null && node != null)
                artefact = TreeHelper.GetParentArtefact(node);
            if (artefact != null)
                readOnly = artefact.IsFinal;


            TreeNode fhl = TreeHelper.GetHierarchyManage(node);

            contextMenu.Items[(int)PopupItem.NewChild].Enabled = readOnly == false &&
                (fhl != null || tag is ISdmxNewChild);
            contextMenu.Items[(int)PopupItem.RedefineParent].Enabled = readOnly == false &&
                (fhl != null && tag is ISdmxHierarchyListItem);

            bool saveArtefactEnable = ((tag is Artefact || tag is MetadataSetType) ||
                (tag is ArtefactManager && (tag as ArtefactManager).Count > 0));
            contextMenu.Items[(int)PopupItem.SaveDocument].Enabled = saveArtefactEnable;
            if (saveSelectedArtefactToolStripMenuItem != null)
                saveSelectedArtefactToolStripMenuItem.Enabled = saveArtefactEnable;
            if (toolStripButtonSaveArtefact != null)
                toolStripButtonSaveArtefact.Enabled = saveArtefactEnable;

            contextMenu.Items[(int)PopupItem.NewVersion].Enabled =
                (tag is Artefact);
            contextMenu.Items[(int)PopupItem.CopyArtefactRef].Enabled =
                (tag is Artefact || tag is ISdmxHierarchyListItem || tag is HierarchyType || tag is AttributeValueSetType);

            contextMenu.Items[(int)PopupItem.DeleteItem].Enabled =
                tag is ArtefactManager && (tag as ArtefactManager).ArtefactList.Count > 0 ||
                ((readOnly == false ||
                node.Parent != null && node.Parent.Tag is ArtefactManager) &&
                (node != null && node.Parent != null &&
                ((fhl != null && fhl != node) || (node.Parent.Tag is ISdmxDelChild) && (tag is CodelistRefTypeList == false))));

            // Copy menu
            contextMenu.Items[(int)PopupItem.Copy].Enabled = tag != null && (tag is ISdmxHierarchyListItem || tag is AttributeValueSetType);

            // Paste menu
            contextMenu.Items[(int)PopupItem.Paste].Enabled = tag != null && readOnly == false &&
                (CanPasteItem(artefact, tag) || GetValidMetasetForPaste() != null);

            // Aczivate Uri
        }

        private bool CanPasteItem(Artefact parent, object tag)
        {
            if (parent != null && (tag is ISdmxHierarchyListItem || tag is IHierarchyManage))
                if (CopyPasteManager.HierarchyItem != null && CopyPasteManager.HierarchyItemParentType == parent.ArType)
                    return true;
            return false;
        }
        #endregion

        #region Copy Item Event

        /// <summary> Copy im CP Manager the ISdmxHierarchyListItem and it's parent type</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void menuItemCopyItem_Click(object sender, EventArgs e)
        {
            try
            {
                Artefact artefact = tv.SelectedNode.Tag  as Artefact;
                if (artefact == null)
                    artefact = TreeHelper.GetParentArtefact(tv.SelectedNode);
                if (artefact != null && tv.SelectedNode.Tag is ISdmxHierarchyListItem)
                {
                    CopyPasteManager.HierarchyItem = (tv.SelectedNode.Tag as ISdmxHierarchyListItem).Clone();
                    CopyPasteManager.HierarchyItemParentType = artefact.ArType;
                    
                    UpdateContextMenu(tv.SelectedNode);
                }

                // Metadataset row
                AttributeValueSetType attVal = tv.SelectedNode.Tag as AttributeValueSetType;
                if (attVal != null)
                {
                    CopyPasteManager.AttributeValue = attVal;

                    UpdateContextMenu(tv.SelectedNode);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Paste Item Event

        /// <summary>Paste from CP Manager the ISdmxHierarchyListItem and insert after current node </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void menuItemPasteItem_Click(object sender, EventArgs e)
        {
            try
            {
                // Assumes validely called
                Artefact artefact = TreeHelper.GetParentArtefact(tv.SelectedNode);
                ISdmxHierarchyListItem selectedItem = tv.SelectedNode.Tag as ISdmxHierarchyListItem;
                IHierarchyManage fhl = null;
                TreeNode fhlNode = TreeHelper.GetHierarchyManage(tv.SelectedNode);
                if (fhlNode != null)
                    fhl = fhlNode.Tag as IHierarchyManage;

                if (artefact != null && fhl != null)
                {
                    // CategoryScheme has a real hierarchy
                    if (fhl is FlatHierarchicalList)
                    {
                        List<ISdmxHierarchyListItem> list = fhl as List<ISdmxHierarchyListItem>;
                        int index = selectedItem == null ? -1 : list.IndexOf(selectedItem);

                        // Update parent, Insert clone at index, refresh tree
                        ISdmxHierarchyListItem newItem = CopyPasteManager.HierarchyItem.Clone();
                        newItem.Parent = index == -1 ? string.Empty : list[index].Parent;
                        // If has parent, set hierarchy flag
                        if (newItem.Parent != null && newItem.Parent.Length > 0)
                            fhl.HasHierarchy = true;

                        // Ensure no ID conflict in new collection
                        newItem.Id = EnsureId(list, newItem.Id);

                        list.Insert(index + 1, newItem);
                        TreeNode ndDummy = new TreeNode();
                        newItem.FillNode(ndDummy);
                        TreeNode newNode = new TreeNode(newItem.ToString(), ndDummy.Nodes[0].ImageIndex, ndDummy.Nodes[0].SelectedImageIndex);
                        newNode.Tag = newItem;
                        if (index == -1)
                        {
                            // Container is selected, insert as 1st node
                            tv.SelectedNode.Nodes.Insert(0, newNode);
                        }
                        else
                        {
                            // Insert after curently selected item
                            int nodeIndex = tv.SelectedNode.Parent.Nodes.IndexOf(tv.SelectedNode);
                            tv.SelectedNode.Parent.Nodes.Insert(nodeIndex + 1, newNode);
                        }
                    }
                    else
                    {
                        NestedHierarchicalList nhl = fhl as NestedHierarchicalList;
                        if (nhl != null)
                        {
                            ISdmxHierarchyListItem newItem = CopyPasteManager.HierarchyItem.Clone();
                            Category cat = newItem as Category;
                            ProcessStepType prt = newItem as ProcessStepType;
                            // the cloned item must receive it's parent and root categorylist
                            if (selectedItem == null)
                            {
                                if (cat != null)
                                {
                                    cat.RootHierarchy = nhl;
                                    cat.ParentCategory = null;
                                }
                                else if (prt != null)
                                {
                                    prt.RootHierarchy = nhl;
                                    prt.ParentStep = null;
                                }
                                // Ensure no ID conflict in new collection
                                newItem.Id = EnsureId(nhl, newItem.Id);

                                nhl.Insert(0, newItem);
                                TreeNode ndDummy = new TreeNode();
                                newItem.FillNode(ndDummy);
                                TreeNode newNode = new TreeNode(newItem.ToString(), ndDummy.Nodes[0].ImageIndex, ndDummy.Nodes[0].SelectedImageIndex);
                                newNode.Tag = newItem;
                                // Container is selected, insert as 1st node
                                tv.SelectedNode.Nodes.Insert(0, newNode);
                            }
                            else
                            {
                                // insert at same level as selected item (after it)
                                ProcessStepType selectedPrt = tv.SelectedNode.Tag as ProcessStepType;
                                Category selectedCat = tv.SelectedNode.Tag as Category;
                                NestedHierarchicalList nhlParent = nhl; // assume at start and correct if needed
                                if (cat != null)
                                {
                                    cat.RootHierarchy = selectedCat.RootHierarchy;
                                    cat.ParentCategory = selectedCat.ParentCategory;
                                    if (cat.ParentCategory != null)
                                        nhlParent = cat.ParentCategory.InnerHierarchy as NestedHierarchicalList;
                                }
                                else if (prt != null)
                                {
                                    prt.RootHierarchy = selectedPrt.RootHierarchy;
                                    prt.ParentStep = selectedPrt.ParentStep;
                                    if (prt.ParentStep != null)
                                        nhlParent = prt.ParentStep.InnerHierarchy as NestedHierarchicalList;
                                }

                                // Ensure no ID conflict in new collection
                                newItem.Id = EnsureId(nhl, newItem.Id);

                                int index = selectedItem == null ? -1 : nhlParent.IndexOf(selectedItem);
                                nhlParent.Insert(index + 1, newItem);
                                TreeNode ndDummy = new TreeNode();
                                newItem.FillNode(ndDummy);
                                TreeNode newNode = new TreeNode(newItem.ToString(), ndDummy.Nodes[0].ImageIndex, ndDummy.Nodes[0].SelectedImageIndex);
                                newNode.Tag = newItem;
                                // Insert after curently selected item
                                int nodeIndex = tv.SelectedNode.Parent.Nodes.IndexOf(tv.SelectedNode);
                                tv.SelectedNode.Parent.Nodes.Insert(nodeIndex + 1, newNode);
                            }
                        }
                    }
                }
                else
                {
                    // Metadataset 
                    MetadataSetType mds = GetValidMetasetForPaste();
                    if (mds != null)
                    {
                        MetadataSetType mdsTarget = artefact as MetadataSetType;
                        if (mdsTarget != null)
                        {
                            // the copy has only on attributeval
                            AttributeValueSetType attSelected = tv.SelectedNode.Tag as AttributeValueSetType;
                            if (attSelected != null)
                            {
                                int index = mdsTarget.AttributeValueSetList.IndexOf(attSelected);
                                AttributeValueSetType attToCopy = CopyPasteManager.AttributeValue.Clone();
                                mdsTarget.AttributeValueSetList.Insert(index + 1, attToCopy);
                                TreeNode ndDummy = new TreeNode();
                                attToCopy.FillNode(ndDummy);
                                TreeNode newNode = new TreeNode(attToCopy.ToString(), ndDummy.Nodes[0].ImageIndex, ndDummy.Nodes[0].SelectedImageIndex);
                                newNode.Tag = attToCopy;
                                // Insert after curently selected item
                                int nodeIndex = tv.SelectedNode.Parent.Nodes.IndexOf(tv.SelectedNode);
                                tv.SelectedNode.Parent.Nodes.Insert(nodeIndex + 1, newNode);

                            }
                        }
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private MetadataSetType GetValidMetasetForPaste()
        {

            MetadataSetType mds = CopyPasteManager.AttributeValue == null ? null : CopyPasteManager.AttributeValue.ParentMetadataSet;
            if (mds != null && tv.SelectedNode != null && tv.SelectedNode.Tag is AttributeValueSetType)
            {
                AttributeValueSetType attVal = tv.SelectedNode.Tag as AttributeValueSetType;
                if (attVal.ParentMetadataSet.MetadataStructureRef.FullIdent == mds.MetadataStructureRef.FullIdent &&
                    attVal.ParentMetadataSet.ReportRef == mds.ReportRef)
                    return mds;
            }
            return null;
        }

        /// <summary> Ensure no ID conflict in new collection </summary>
        /// <param name="list">list of existing</param>
        /// <param name="submitedId">new proposed ID</param>
        /// <returns>ID corrected in case of conflict</returns>
        private string EnsureId(IEnumerable<ISdmxHierarchyListItem> list, string submitedId)
        {
            string newId = submitedId;

            // Ensure no ID conflict in new collection
            Dictionary<string, string> h = new Dictionary<string, string>();
            foreach (ISdmxHierarchyListItem item in list)
                h.Add(item.Id, item.Id);
            int nb = 1;
            while (h.ContainsKey(newId))
            {
                newId = "undefined" + nb.ToString();
                nb++;
            }
            return newId;
        }
        #endregion

        #region Redefine Parent Event

        /// <summary>
        /// Redefines Parent of selected Item. Caution: in categories same code value is allowed in
        /// different levels of hierarchy.
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void menuItemRedefineParent_Click(object sender, EventArgs e)
        {
            try
            {
                IHierarchyManage fhl = null;
                TreeNode fhlNode = TreeHelper.GetHierarchyManage(tv.SelectedNode);
                if (fhlNode != null)
                    fhl = fhlNode.Tag as IHierarchyManage;

                if (fhl != null && panelDetail != null)
                {
                    panelDetail.BindFromNode(null);
                    ISdmxHierarchyListItem item = tv.SelectedNode.Tag as ISdmxHierarchyListItem;
                    ArtefactManager arm = TreeHelper.GetParentArtefactManager(tv.SelectedNode);
                    TreeNode parentArtefactNode = TreeHelper.GetParentArtefactNode(tv.SelectedNode);
                    Artefact a = parentArtefactNode.Tag as Artefact;
                    DlgChangeParent dlgRedefine = new DlgChangeParent(item, a, fhl);

                    if (a != null && arm != null && dlgRedefine.ShowDialog() == DialogResult.OK && dlgRedefine.Clone != null)
                    {
                        int index = arm.ArtefactList.IndexOf(a);
                        arm.ArtefactList.Insert(index, dlgRedefine.Clone);
                        arm.ArtefactList.Remove(a);
                        parentArtefactNode.Tag = dlgRedefine.Clone;
                        fhlNode.Nodes.Clear();
                        fhlNode.Tag = dlgRedefine.ihManage;
                        dlgRedefine.ihManage.HasHierarchy = true;
                        dlgRedefine.ihManage.FillTree(fhlNode);
                        tv.SelectedNode = parentArtefactNode;
                        tv.SelectedNode.Expand();
                        tv.SelectedNode.EnsureVisible();
                        tv.EndUpdate();
                    }

                    else
                        panelDetail.BindFromNode(tv.SelectedNode);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Popup", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Delete Item Event

        /// <summary>
        /// Delete selected Node and it's childs from tree and from Artefact parent collection
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void menuItemDelete_Click(object sender, EventArgs e)
        {
            try
            {
                // Do we delete all artefacts of a container ?
                if (tv.SelectedNode != null && tv.SelectedNode.Tag is ArtefactManager)
                {
                    ArtefactManager arm = tv.SelectedNode.Tag as ArtefactManager;
                    if (MessageBox.Show(string.Format("Delete all {0} Artefacts?", arm.ToString()), "Check",
                             MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        arm.ArtefactList.Clear();
                        tv.SelectedNode.Nodes.Clear();
                    }
                }
                else
                {
                    IHierarchyManage fhl = null;
                    ISdmxDelChild am = null;
                    TreeNode fhlNode = TreeHelper.GetHierarchyManage(tv.SelectedNode);
                    if (fhlNode != null && fhlNode != tv.SelectedNode)
                        fhl = fhlNode.Tag as IHierarchyManage;
                    else if (tv.SelectedNode.Parent != null && (tv.SelectedNode.Tag is CodelistRefTypeList == false))
                        am = tv.SelectedNode.Parent.Tag as ISdmxDelChild;

                    if (fhl != null || am != null)
                    {
                        if (MessageBox.Show("Delete selected item and its childs?", "Check",
                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            TreeNode target = tv.SelectedNode;
                            tv.SelectedNode = tv.SelectedNode.Parent;
                            if (fhlNode != null)
                            {
                                ISdmxHierarchyListItem child = target.Tag as ISdmxHierarchyListItem;
                                if (child != null)
                                    fhl.RemoveHierarchicalItem(child);
                            }
                            else if (am != null)
                            {
                                am.DelChild(target.Tag);
                            }

                            tv.BeginUpdate();
                            target.Nodes.Clear();
                            tv.SelectedNode.Nodes.Remove(target);

                            tv.SelectedNode.Expand();
                            tv.SelectedNode.EnsureVisible();
                            tv.EndUpdate();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Popup", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region New Child Item

        void menuItemNewChild_Click(object sender, EventArgs e)
        {
            if (tv.SelectedNode != null)
            {
                try
                {
                    IHierarchyManage fhl = null;
                    ISdmxNewChild nch = null;
                    TreeNode t = null;
                    nch = tv.SelectedNode.Tag as ISdmxNewChild;
                    TreeNode fhlNode = TreeHelper.GetHierarchyManage(tv.SelectedNode);
                    if (fhlNode != null)
                    {
                        fhl = fhlNode.Tag as IHierarchyManage;
                        t = fhl.NewChild(tv.SelectedNode);
                    }
                    else if (nch != null)
                        t = nch.NewChild(tv.SelectedNode);
                    if (t != null)
                    {
                        tv.SelectedNode = t;
                        t.EnsureVisible();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Popup", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        #endregion

        #region Copy Reference event

        void menuItemCopyArtefactRef_Click(object sender, EventArgs e)
        {
            //Raise update event for main program
            if (CopyArtefactRefEventExposed != null)
                CopyArtefactRefEventExposed(this, EventArgs.Empty);
        }
        #endregion

        #region Save artefact Event

        void menuItemSaveArtefact_Click(object sender, EventArgs e)
        {
            //Raise update event for main program
            if (SaveArtefactEventExposed != null)
                SaveArtefactEventExposed(this, EventArgs.Empty);
        }
        #endregion

        #region New Artefact Version event

        void menuItemNewArtefactVersion_Click(object sender, EventArgs e)
        {
            if (tv.SelectedNode != null)
            {
                TreeNode nodeCreated = tv.SelectedNode;

                Artefact a = tv.SelectedNode.Tag as Artefact;
                ArtefactManager am = tv.SelectedNode.Parent.Tag as ArtefactManager;
                if (a != null && am != null)
                {
                    int previousCount = am.Count;
                    am.CreateNewVersion(a);
                    nodeCreated = am.FillNode(tv.SelectedNode.Parent, previousCount);
                    if (nodeCreated != null)
                        nodeCreated.Expand();
                }
                //TODO
                else if (tv.SelectedNode.Tag is MetadataSetType)
                {
                    MetadataSetManager mdsm = tv.SelectedNode.Parent.Tag as MetadataSetManager;
                }

                tv.SelectedNode = nodeCreated;
            }
        }
        #endregion

        #region Uri Activation event

        void menuItemActivateUri_Click(object sender, EventArgs e)
        {
            try
            {
                if (tv.SelectedNode != null && tv.SelectedNode.Tag is Artefact)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        Artefact a = tv.SelectedNode.Tag as Artefact;
                        // If URN try to get it if not already in memory
                        ArtefactRefTyped art = UrnManager.UrnToArtefactRefTyped(a.Uri);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        




        #endregion
    }
}
